﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using HCMServices.DAO;
using System.Collections.Generic;
using HCMServices.DTO;

namespace HCMServices.BUS
{
    /// <summary>
    /// This class help to show suggested place for user when they search
    /// </summary>
    public class AutoComplete
    {
        public int _MAX_SUGGESTION = 7;
        private string connectString = "Data Source = isostore:/Database.sdf";

        private ServiceDAO _serviceDAO = null;
        private DataDAO _dataDAO = null;
        private StreetDAO _streetDAO = null;
        private WardDAO _wardDAO = null;
        private DistrictDAO _districtDAO = null;
        private PlaceNameDAO _placeNameDAO = null;
        private CityDAO _cityDAO = null;
        private KeyPlaceNameDAO _keyPlaceNameDAO = null;
        private KeyServiceDAO _keyServiceDAO = null;
        private KeyStreetDAO _keyStreetDAO = null;
        private KeyWardDAO _keyWardDAO = null;
        private KeyDistrictDAO _keyDistrictDAO = null;
        private KeyCityDAO _keyCityDAO = null;

        private List<string> _lstResult = null;

        /// <summary>
        /// This class contain information of suggest object
        /// </summary>
        public class SuggestObject
        {
            private string _original;

            public string Original
            {
                get { return _original; }
                set { _original = value; }
            }

            private string _keyword;

            public string Keyword
            {
                get { return _keyword; }
                set { _keyword = value; }
            }
        }

        private List<string> _slstServiceDTO = new List<string>();
        private List<string> _slstStreetDTO = new List<string>();
        private List<string> _slstWardDTO = new List<string>();
        private List<string> _slstDistrictDTO = new List<string>();
        private List<string> _slstKeyServiceDTO = new List<string>();
        private List<string> _slstKeyStreetDTO = new List<string>();
        private List<string> _slstKeyWardDTO = new List<string>();
        private List<string> _slstKeyDistrictDTO = new List<string>();

        /// <summary>
        /// Constructor of AutoComplete class
        /// </summary>
        public AutoComplete()
        {
            this._serviceDAO = new ServiceDAO(connectString);
            this._dataDAO = new DataDAO(connectString);
            this._streetDAO = new StreetDAO(connectString);
            this._wardDAO = new WardDAO(connectString);
            this._districtDAO = new DistrictDAO(connectString);
            this._placeNameDAO = new PlaceNameDAO(connectString);
            this._cityDAO = new CityDAO(connectString);
            this._keyPlaceNameDAO = new KeyPlaceNameDAO(connectString);
            this._keyServiceDAO = new KeyServiceDAO(connectString);
            this._keyStreetDAO = new KeyStreetDAO(connectString);
            this._keyWardDAO = new KeyWardDAO(connectString);
            this._keyDistrictDAO = new KeyDistrictDAO(connectString);
            this._keyCityDAO = new KeyCityDAO(connectString);

            this._lstResult = new List<string>();

            List<DistrictDTO> lstDistrictDTO = this.GetAllDistrictDTO();
            List<WardDTO> lstWardDTO = this.GetAllWardDTO();
            List<StreetDTO> lstStreetDTO = this.GetAllStreetDTO();
            List<ServiceDTO> lstServiceDTO = this.GetAllServiceDTO();

            this._slstDistrictDTO = new List<string>();
            foreach (DistrictDTO districtDTO in lstDistrictDTO)
            {
                this._slstKeyDistrictDTO.Add(SearchUtilities.FormatInputData(districtDTO.Name));
                this._slstDistrictDTO.Add(districtDTO.Name);
            }

            this._slstWardDTO = new List<string>();
            foreach (WardDTO wardDTO in lstWardDTO)
            {
                    this._slstKeyWardDTO.Add(SearchUtilities.FormatInputData(wardDTO.Name));
                    this._slstWardDTO.Add(wardDTO.Name);
            }

            this._slstStreetDTO = new List<string>();
            foreach (StreetDTO streetDTO in lstStreetDTO)
            {
                this._slstKeyStreetDTO.Add(SearchUtilities.FormatInputData(streetDTO.Name));
                this._slstStreetDTO.Add(streetDTO.Name);
            }

            this._slstServiceDTO = new List<string>();
            foreach (ServiceDTO serviceDTO in lstServiceDTO)
            {
                this._slstKeyServiceDTO.Add(SearchUtilities.FormatInputData(serviceDTO.Name));
                this._slstServiceDTO.Add(serviceDTO.Name);
            }
        }

        private List<DistrictDTO> GetAllDistrictDTO()
        {
            List<DistrictDTO> lstDistrictDTO = null;

            lstDistrictDTO = this._districtDAO.GetAllQuanHuyenDTO();

            return lstDistrictDTO;
        }

        private List<WardDTO> GetAllWardDTO()
        {
            List<WardDTO> lstWardDTO = null;

            lstWardDTO = this._wardDAO.GetAllPhuongDTO();

            return lstWardDTO;
        }

        private List<StreetDTO> GetAllStreetDTO()
        {
            List<StreetDTO> lstStreetDTO = null;

            lstStreetDTO = this._streetDAO.GetAllDuongDTO();

            return lstStreetDTO;
        }

        private List<ServiceDTO> GetAllServiceDTO()
        {
            List<ServiceDTO> lstServiceDTO = null;

            lstServiceDTO = this._serviceDAO.GetAllDichVuDTO();

            return lstServiceDTO;
        }

        private void Analysis(string strInput, string tenDichVu, string tenDuong, string tenPhuong, string tenQuanHuyen)
        {
            if (_MAX_SUGGESTION == this._lstResult.Count)
            {
                return;
            }

            if (0 == strInput.Length)
            {
                string strTemp = string.Empty;
                if (tenDichVu.Length > 0)
                {
                    strTemp += tenDichVu;
                    strTemp += " ";
                }

                if (tenDuong.Length > 0)
                {
                    strTemp += tenDuong;
                    strTemp += " ";
                }

                if (tenPhuong.Length > 0)
                {
                    strTemp += tenPhuong;
                    strTemp += " ";
                }

                if (tenQuanHuyen.Length > 0)
                {
                    strTemp += tenQuanHuyen;
                    strTemp += " ";
                }

                strTemp = strTemp.Trim();
                this._lstResult.Add(strTemp);
            }

            if (0 == tenDichVu.Length)
            {
                List<string> lstDichVu = this.GetObjectContainInList(this._slstKeyServiceDTO, this._slstServiceDTO, strInput);
             
                string strTemp = string.Empty;
                for (int i = 0; i < lstDichVu.Count; i++)
                {
                    string keyword = SearchUtilities.FormatInputData(lstDichVu[i]);
                    if (keyword.StartsWith(strInput))
                    {
                        strTemp = string.Empty;
                    }
                    else
                    {
                        strTemp = strInput.Replace(keyword, string.Empty).Trim();
                    }

                    Analysis(strTemp, lstDichVu[i], tenDuong, tenPhuong, tenQuanHuyen);
                    if (lstDichVu[i].ToLower() != SearchUtilities.FormatInputData(lstDichVu[i]))
                    {
                        Analysis(strTemp, SearchUtilities.FormatInputData(lstDichVu[i]), tenDuong, tenPhuong, tenQuanHuyen);
                    }
                }
            }

            if (0 == tenDuong.Length)
            {
                ////List<string> lstDuong = this._slstStreetDTO.Where(x => x.Key.StartsWith(strInput) | strInput.StartsWith(x.Key)).Select(x => x.Value).ToList<string>();
                List<string> lstDuong = this.GetObjectContainInList(this._slstKeyStreetDTO, this._slstStreetDTO, strInput);
                string strTemp = string.Empty;
                for (int i = 0; i < lstDuong.Count; i++)
                {
                    string keyword = SearchUtilities.FormatInputData(lstDuong[i]);
                    if (keyword.StartsWith(strInput))
                    {
                        strTemp = string.Empty;
                    }
                    else
                    {
                        strTemp = strInput.Replace(keyword, string.Empty).Trim();
                    }

                    Analysis(strTemp, tenDichVu, lstDuong[i], tenPhuong, tenQuanHuyen);
                    if (lstDuong[i].ToLower() != SearchUtilities.FormatInputData(lstDuong[i]))
                    {
                        Analysis(strTemp, tenDichVu, SearchUtilities.FormatInputData(lstDuong[i]), tenPhuong, tenQuanHuyen);
                    }
                }
            }

            if (0 == tenPhuong.Length)
            {
                ////List<string> lstPhuong = this._slstWardDTO.Where(x => x.Key.StartsWith(strInput) | strInput.StartsWith(x.Key)).Select(x => x.Value).ToList<string>();
                List<string> lstPhuong = this.GetObjectContainInList(this._slstKeyWardDTO, this._slstWardDTO, strInput);
                string strTemp = string.Empty;
                for (int i = 0; i < lstPhuong.Count; i++)
                {
                    string keyword = SearchUtilities.FormatInputData(lstPhuong[i]);
                    if (keyword.StartsWith(strInput))
                    {
                        strTemp = string.Empty;
                    }
                    else
                    {
                        strTemp = strInput.Replace(keyword, string.Empty).Trim();
                    }

                    Analysis(strTemp, tenDichVu, tenDuong, lstPhuong[i], tenQuanHuyen);
                    if (lstPhuong[i].ToLower() != SearchUtilities.FormatInputData(lstPhuong[i]))
                    {
                        Analysis(strTemp, tenDichVu, tenDuong, SearchUtilities.FormatInputData(lstPhuong[i]), tenQuanHuyen);
                    }
                }
            }

            if (0 == tenQuanHuyen.Length)
            {
                ////List<string> lstQuanHuyen = this._slstDistrictDTO.Where(x => x.Key.StartsWith(strInput) | strInput.StartsWith(x.Key)).Select(x => x.Value).ToList<string>();
                List<string> lstQuanHuyen = this.GetObjectContainInList(this._slstKeyDistrictDTO, this._slstDistrictDTO, strInput);
                string strTemp = string.Empty;
                for (int i = 0; i < lstQuanHuyen.Count; i++)
                {
                    string keyword = SearchUtilities.FormatInputData(lstQuanHuyen[i]);
                    if (keyword.StartsWith(strInput))
                    {
                        strTemp = string.Empty;
                    }
                    else
                    {
                        strTemp = strInput.Replace(keyword, string.Empty).Trim();
                    }

                    Analysis(strTemp, tenDichVu, tenDuong, tenPhuong, lstQuanHuyen[i]);
                    if (lstQuanHuyen[i].ToLower() != SearchUtilities.FormatInputData(lstQuanHuyen[i]))
                    {
                        Analysis(strTemp, tenDichVu, tenDuong, tenPhuong, SearchUtilities.FormatInputData(lstQuanHuyen[i]));
                    }
                }
            }
        }

        private List<string> GetObjectContainInList(List<string> key, List<string> value, string strInput)
        {
            /*this._slstServiceDTO.Where(x => x.Key.StartsWith(strInput) | strInput.StartsWith(x.Key)).
            Select(x => x.Value).ToList<string>();*/
            List<string> result = new List<string>();

            for (int i = 0; i < key.Count; i++)
            {
                if (key[i].StartsWith(strInput) | strInput.StartsWith(key[i]))
                {
                    result.Add(value[i]);
                }
            }

            return result;
        }

        /// <summary>
        /// Find suggest object from keyword which user type
        /// </summary>
        /// <param name="strInput">Keyword to analysis</param>
        /// <returns>List of string contain place is suggested</returns>
        public List<string> Suggest(string strInput)
        {
            List<string> lstRet = null;
            try
            {
                if (null != this._lstResult)
                {
                    this._lstResult.Clear();
                }
                else
                {
                    this._lstResult = new List<string>();
                }

                strInput = SearchUtilities.FormatInputData(strInput);
                this.Analysis(strInput, string.Empty, string.Empty, string.Empty, string.Empty);
                lstRet = this._lstResult;
            }
            catch (System.Exception ex)
            {
                lstRet = new List<string>();
                ex.ToString();
            }

            return lstRet;
        }

        private List<KeyPlaceNameDTO> AutoCompleteTuKhoaDiaDiem(string strInput)
        {
            strInput = SearchUtilities.FormatInputData(strInput);
            List<KeyPlaceNameDTO> lstTuKhoaDiaDiem = new List<KeyPlaceNameDTO>();

            lstTuKhoaDiaDiem = this._keyPlaceNameDAO.AutoCompleteTuKhoaDiaDiem(strInput);

            return lstTuKhoaDiaDiem;
        }

        private List<KeyStreetDTO> AutoCompleteTuKhoaDuong(string strInput)
        {
            strInput = SearchUtilities.FormatInputData(strInput);
            List<KeyStreetDTO> lstTuKhoaDuong = new List<KeyStreetDTO>();

            lstTuKhoaDuong = this._keyStreetDAO.AutoCompleteTuKhoaDuong(strInput);

            return lstTuKhoaDuong;
        }

        private List<KeyPlaceNameDTO> AutoCompleteTuKhoaDiaDiemTheoDichVu(string strInput, int maDichVu)
        {
            strInput = SearchUtilities.FormatInputData(strInput);
            List<KeyPlaceNameDTO> lstTuKhoaDiaDiem = new List<KeyPlaceNameDTO>();

            lstTuKhoaDiaDiem = this._keyPlaceNameDAO.AutoCompleteTuKhoaDiaDiemTheoDichVu(strInput, maDichVu);

            return lstTuKhoaDiaDiem;
        }

        private List<KeyStreetDTO> AutoCompleteTuKhoaDuongTheoDichVu(string strInput, int maDichVu)
        {
            strInput = SearchUtilities.FormatInputData(strInput);
            strInput.Trim();
            List<KeyStreetDTO> lstTuKhoaDuong = new List<KeyStreetDTO>();

            lstTuKhoaDuong = this._keyStreetDAO.AutoCompleteTuKhoaDuongTheoDichVu(strInput, maDichVu);

            return lstTuKhoaDuong;
        }
    }
}
